/**
 * 角色服务
 * 作者：GodMainCode
 * 创建时间：2024-01-17
 * 修改时间：2024-01-17
 * 修改人：GodMainCode
 */

import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, In } from 'typeorm';
import { Role } from './entities/role.entity';
import { Permission } from '../permission/entities/permission.entity';
import { CreateRoleDto } from './dto/create-role.dto';
import { UpdateRoleDto } from './dto/update-role.dto';

@Injectable()
export class RoleService {
  constructor(
    @InjectRepository(Role)
    private readonly roleRepository: Repository<Role>,
    @InjectRepository(Permission)
    private readonly permissionRepository: Repository<Permission>,
  ) {}

  /**
   * 创建角色
   * @param createRoleDto 创建角色数据
   * @returns Promise<Role> 创建的角色信息
   */
  async create(createRoleDto: CreateRoleDto): Promise<Role> {
    const { permissionIds, ...roleData } = createRoleDto;

    // 查找权限
    const permissions = await this.permissionRepository.findBy({
      id: In(permissionIds),
      is_deleted: 0,
    });

    // 创建角色
    const role = this.roleRepository.create({
      ...roleData,
      permissions,
    });

    return await this.roleRepository.save(role);
  }

  /**
   * 获取所有角色
   * @returns Promise<Role[]> 角色列表
   */
  async findAll(): Promise<Role[]> {
    return await this.roleRepository.find({
      where: { is_deleted: 0 },
      relations: ['permissions'],
      order: { sort: 'ASC' },
    });
  }

  /**
   * 获取角色详情
   * @param id 角色ID
   * @returns Promise<Role> 角色信息
   */
  async findOne(id: number): Promise<Role> {
    const role = await this.roleRepository.findOne({
      where: { id, is_deleted: 0 },
      relations: ['permissions'],
    });

    if (!role) {
      throw new NotFoundException(`ID为${id}的角色不存在`);
    }

    return role;
  }

  /**
   * 更新角色
   * @param id 角色ID
   * @param updateRoleDto 更新角色数据
   * @returns Promise<Role> 更新后的角色信息
   */
  async update(id: number, updateRoleDto: UpdateRoleDto): Promise<Role> {
    const { permissionIds, ...roleData } = updateRoleDto;
    const role = await this.findOne(id);

    if (permissionIds) {
      const permissions = await this.permissionRepository.findBy({
        id: In(permissionIds),
        is_deleted: 0,
      });
      role.permissions = permissions;
    }

    Object.assign(role, roleData);
    return await this.roleRepository.save(role);
  }

  /**
   * 删除角色
   * @param id 角色ID
   */
  async remove(id: number): Promise<void> {
    const role = await this.findOne(id);
    role.is_deleted = 1;
    await this.roleRepository.save(role);
  }

  /**
   * 根据角色标识查找角色
   * @param code 角色标识
   * @returns Promise<Role> 角色信息
   */
  async findByCode(code: string): Promise<Role | null> {
    return await this.roleRepository.findOne({
      where: { code, is_deleted: 0 },
      relations: ['permissions'],
    });
  }
} 